namespace RBAC.Write.Api.Application.Handler.BomHandler
{
    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.Linq;
    using System.Text;
    using Dapper;
    using MediatR;
    using Microsoft.Extensions.Logging;
    using RBAC.ErrorCode;
    using RBAC.Interstructrue.Base;
    using RBAC.Write.Api.Application.Command.BomCommand;

    /// <summary>
    /// 编辑BOM 处理器（仅允许修改名称、版本、单位、修订说明、状态）
    /// </summary>
    public class BomUpdateHandler : IRequestHandler<BomUpdateCommand, APIResult<int>>
    {
        private readonly IDbConnectionFactory _connectionFactory;
        private readonly ILogger<BomUpdateHandler> _logger;

        public BomUpdateHandler(IDbConnectionFactory connectionFactory, ILogger<BomUpdateHandler> logger)
        {
            _connectionFactory = connectionFactory;
            _logger = logger;
        }

        /// <summary>
        /// 处理BOM编辑请求。仅更新请求中显式提供的字段，避免将未提供字段置空。
        /// </summary>
        public async Task<APIResult<int>> Handle(BomUpdateCommand request, CancellationToken cancellationToken)
        {
            var result = new APIResult<int>();
            try
            {
                cancellationToken.ThrowIfCancellationRequested();

                if (request.Id <= 0)
                    return new APIResult<int> { Code = APIEnums.Fail, Msg = "参数无效：Id 必须大于 0", Data = 0 };

                using var connection = _connectionFactory.CreateConnectionWithRetry();
                using var transaction = connection.BeginTransaction(IsolationLevel.ReadCommitted);

                try
                {
                    // 1) 存在性校验（未删除）
                    const string sqlCheck = "SELECT COUNT(1) FROM Bom WHERE Id = @Id AND IsDeleted = 0";
                    var exists = await connection.ExecuteScalarAsync<int>(new CommandDefinition(sqlCheck, new { request.Id }, transaction: transaction));
                    if (exists <= 0)
                    {
                        transaction.Rollback();
                        return new APIResult<int> { Code = APIEnums.Fail, Msg = "BOM不存在或已删除", Data = 0 };
                    }

                    // 2) 组装动态更新字段（仅更新提供的字段）
                    var setParts = new List<string>();
                    var parameters = new DynamicParameters();
                    parameters.Add("Id", request.Id);

                    if (!string.IsNullOrWhiteSpace(request.Name))
                    {
                        setParts.Add("Name = @Name");
                        parameters.Add("Name", request.Name.Trim());
                    }
                    if (!string.IsNullOrWhiteSpace(request.Version))
                    {
                        setParts.Add("Version = @Version");
                        parameters.Add("Version", request.Version!.Trim());
                    }
                    if (!string.IsNullOrWhiteSpace(request.Unit))
                    {
                        setParts.Add("Unit = @Unit");
                        parameters.Add("Unit", request.Unit!.Trim());
                    }
                    if (!string.IsNullOrWhiteSpace(request.RevisionNotes))
                    {
                        setParts.Add("RevisionNotes = @RevisionNotes");
                        parameters.Add("RevisionNotes", request.RevisionNotes!.Trim());
                    }
                    if (request.Status.HasValue)
                    {
                        setParts.Add("Status = @Status");
                        parameters.Add("Status", request.Status.Value);
                    }

                    if (!setParts.Any())
                    {
                        transaction.Rollback();
                        return new APIResult<int> { Code = APIEnums.Fail, Msg = "无可更新字段", Data = 0 };
                    }

                    var sql = $"UPDATE Bom SET {string.Join(", ", setParts)} WHERE Id = @Id AND IsDeleted = 0";
                    var affected = await connection.ExecuteAsync(new CommandDefinition(sql, parameters, transaction));

                    transaction.Commit();

                    result.Code = affected > 0 ? APIEnums.Success : APIEnums.Fail;
                    result.Msg = affected > 0 ? "编辑BOM成功" : "编辑BOM失败";
                    result.Data = affected;
                }
                catch (OperationCanceledException)
                {
                    transaction.Rollback();
                    _logger?.LogWarning("编辑BOM被取消");
                    result.Code = APIEnums.Fail;
                    result.Msg = "请求已取消";
                    result.Data = 0;
                }
                catch (Exception ex)
                {
                    transaction.Rollback();
                    _logger?.LogError(ex, "编辑BOM异常: {Message}", ex.Message);
                    result.Code = APIEnums.Fail;
                    result.Msg = "编辑BOM异常: " + ex.Message;
                    result.Data = 0;
                }
            }
            catch (OperationCanceledException)
            {
                _logger?.LogWarning("编辑BOM被取消");
                result.Code = APIEnums.Fail;
                result.Msg = "请求已取消";
                result.Data = 0;
            }
            catch (Exception ex)
            {
                _logger?.LogError(ex, "编辑BOM外层异常: {Message}", ex.Message);
                result.Code = APIEnums.Fail;
                result.Msg = "编辑BOM异常: " + ex.Message;
                result.Data = 0;
            }

            return result;
        }
    }
}
